package cn.oowoo.rabbitmq.confirm;

import cn.oowoo.rabbitmq.config.RabbitConfig;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.ConfirmListener;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
* @Author: Zhangbin
* @Date: 11:23 2021/5/9
* @Description: confirm模式异步确认测试-生产者
**/
public class AsyncConfirmProducer {

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = RabbitConfig.createConnection();
        // 创建消息通道
        Channel channel = connection.createChannel();
        //开启发送方确认模式
        channel.confirmSelect();

        for(int i=0;i<5;i++){
            String msg = "测试confirm消息.... "+i;
            channel.basicPublish("",RabbitConfig.QUEUE_CONFIRM_NAME,null,msg.getBytes());
        }

        //异步监听确认和未确认的消息
        channel.addConfirmListener(new ConfirmListener() {
            public void handleNack(long deliveryTag, boolean multiple) throws IOException {
                System.out.println("Broker未确认消息，标识：" + deliveryTag);
            }
            public void handleAck(long deliveryTag, boolean multiple) throws IOException {
                // 如果true表示批量执行了deliveryTag这个值以前（小于deliveryTag的）的所有消息，如果为false的话表示单条确认
                System.out.println(String.format("异步Broker已确认消息，标识：%d，多个消息：%b", deliveryTag, multiple));
            }
            /*
                1、什么时候会走 handleNack 方法呢，比如磁盘写满了，MQ出现了一些异常，或者Queue容量到达上限了等等
                2、也有可能两个方法都不走，比如生产端发送消息就失败了，或者Broker端收到消息在返回ack时中途出现了网络闪断。
                3、这种情况就需要定时任务去抓取中间状态的消息进行最大努力尝试次数的补偿重发，从而保障消息投递的可靠性。
             */
        });
        System.out.println("程序执行完成");

        //消息发送完毕关闭信道，关闭链接(不关闭，测试异步confirm消息监听)
       // channel.close();
       // connection.close();
    }
}
